import { useState, useMemo, useEffect } from "react";
import { createPortal } from "react-dom";
import { Space, Popconfirm, Dropdown } from "antd";
import { DeleteOutlined } from "@ant-design/icons";
import { useComponentsStore, getComponentById } from "../../stores/components";

interface SelectedMaskProps {
    componentId: number;
    containerClassName: string;
    portalWrapperClassName: string;
}

export const SelectedMask = ({ componentId, containerClassName, portalWrapperClassName }: SelectedMaskProps)=>{
    const [position, setPosition] = useState({
        left: 0,
        top: 0,
        width: 0,
        height: 0,
        labelTop: 0,
        labelLeft: 0
    })

    const { components ,curComponentId, deleteComponent, setCurComponentId } = useComponentsStore();

    const el = useMemo(()=>{
        return document.querySelector(`.${portalWrapperClassName}`)!
    }, []);
    const curComponent = useMemo(()=>{
        return getComponentById(componentId, components);
    }, [componentId]);

    const parentComponents = useMemo(()=>{
        const parentComponents = [];
        let component = curComponent;
        while(component?.parentId) {
            component = getComponentById(component.parentId, components);
            parentComponents.push(component);
        }

        return parentComponents;
    }, [curComponent]);

    const updatePosition = ()=>{
        if(!componentId) return;
        const container = document.querySelector(`.${containerClassName}`);
        if(!container) return;
        const node = document.querySelector(`[data-component-id="${componentId}"]`);
        if(!node) return;

        const { top, left, width, height } = node.getBoundingClientRect();
        const { top: containerTop, left: containerLeft } = container.getBoundingClientRect();
        let labelTop = top - containerTop + container.scrollTop;
        let labelLeft = left - containerLeft + width;

        if(labelTop <= 0) labelTop -= -20;

        setPosition({
            top: top - containerTop + container.scrollTop,
            left: left - containerLeft + container.scrollTop,
            width,
            height,
            labelTop,
            labelLeft
        })
    }
    const handleDelete = () => {
        deleteComponent(curComponentId!);
        setCurComponentId(null);
    }

    useEffect(()=>{
        updatePosition();
    }, [componentId]);

    // 实际发现 components 变了，但是组件编辑框大小没变，这是因为 components变化，然后重新组件渲染，但是getBoundingClientRect 拿到组件改变后的宽高是有一段时间的，原因就是组件渲染完了，才计算出了变化后的宽高，然后组件就不再渲染了，所以加个延时就可以了
    useEffect(()=>{
        setTimeout(()=>{
            updatePosition();
        }, 200)
    }, [components]);

    /* 解决调整窗口大小的，这时候编辑框没有重新计算位置 */
    useEffect(()=>{
        const resizeHandle = ()=>{
            updatePosition();
        }

        window.removeEventListener('resize', resizeHandle);

        return ()=>{
            window.removeEventListener('resize', resizeHandle)
        }
    }, [])

    return createPortal((
        <>
            <div style={{
                position: 'absolute',
                left: position.left,
                top: position.top,
                backgroundColor: "rgba(0,0,255,.1)",
                border: "1px solid blue",
                pointerEvents: 'none',
                width: position.width,
                height: position.height,
                zIndex: 12,
                borderRadius: 4,
                boxSizing: 'border-box'
            }} />
            <div style={{
                position:'absolute',
                left: position.labelLeft,
                top: position.labelTop,
                fontSize: '14px',
                zIndex: 13,
                display: (!position.width || position.width < 10) ? 'none' : "inline",
                transform: 'translate(-100%, -100%)'
            }}>
                <Space>
                    <Dropdown menu={{
                        items: parentComponents.map(item => ({
                            key: item?.id,
                            label: item?.desc,
                            type: 'group'
                        })),
                        onClick: ({key})=>{
                            setCurComponentId(+key)
                        }
                    }} disabled={parentComponents.length === 0}>
                        <div style={{
                        padding: '0 8px',
                        backgroundColor: 'blue',
                        borderRadius: 4,
                        color: '#fff',
                        cursor: 'pointer',
                        whiteSpace: "nowrap"
                    }}>
                        { curComponent?.desc }
                    </div>
                    </Dropdown>
                    {
                        curComponentId !== 1 && (
                            <div style={{padding: '0 8px', backgroundColor: 'blue'}}>
                                <Popconfirm title="确认删除？" okText={'确认'} cancelText="取消" onConfirm={handleDelete}>
                                    <DeleteOutlined style={{color: '#fff'}} />
                                </Popconfirm>
                            </div>
                        )
                    }
                </Space>
            </div>
        </>
    ), el)
}